package d2;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiAttendanceListRequest;
import com.dingtalk.api.response.OapiAttendanceListResponse;
import com.dingtalk.api.response.OapiUserListbypageResponse.Userlist;
import com.dingtalk.api.response.OapiAttendanceListResponse.Recordresult;

import cn.cybozu.api.KintoneRecord;


public class D2TimeCardResultConnector extends D2Connector
{
	//modify
	private static final int LIMIT_USER_SIZE = 7;
	private static final long LIMIT_TIMECARD_SIZE = 50;
	
	private Map<String, Userlist> users;
	
	public D2TimeCardResultConnector(String appKey, String appSecret, String domain, long appId, long spaceId, String apiToken)
	{
		super(appKey, appSecret, domain, appId, spaceId, apiToken);
	}
	
	public void execute(Date startDate, Date endDate)
		throws Exception
	{

		users = getAllUsers();
		int count = users.size();
		deleteTimeCardResult(startDate, endDate);		
		List<String> userIds = new ArrayList<>();
		
		for(String id: users.keySet())
		{
			userIds.add(id);
			if(userIds.size() == count)
			{
				getTimeCardResult(userIds, startDate, endDate);
				userIds.clear();
			}
		}
		if(userIds.size() != 0)
		{
			getTimeCardResult(userIds, startDate, endDate);
		}		
	}
	/**
	 * 結果の削除
	 * @throws Exception
	 */
	private void deleteTimeCardResult(Date startDate, Date endDate)
		throws Exception
	{
		String query = "workDate >= \"" + formatDate(startDate) + "\" and workDate <= \"" + formatDate(endDate) + "\"";
		
		List<KintoneRecord> recs = getRecordsFromKintone(query, new String[] {"$id"});
		if(recs.size() == 0)
		{
			return;
		}
		deleteRecordsToKintone(recs);
	}
	private void getTimeCardResult(List<String> userIds, Date startDate, Date endDate)
		throws Exception
	{
		DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/list");
		OapiAttendanceListRequest request = new OapiAttendanceListRequest();
		request.setUserIdList(userIds);
		request.setLimit(LIMIT_TIMECARD_SIZE);
		Date tmpDate = (Date)startDate.clone();
	
		while(tmpDate.compareTo(endDate) <= 0)
		{
			request.setWorkDateFrom(formatDate(tmpDate) + " 00:00:00");
			request.setWorkDateTo(formatDate(tmpDate) + " 00:00:00");
			
			long offset = 0;
			
			for(;;)
			{
				request.setOffset(offset);
				OapiAttendanceListResponse response = client.execute(request, getAccessToken());
				
				if(response.getErrcode() != 0)
				{
					throw new Exception(response.getErrmsg());
				}
				List<Recordresult> list = response.getRecordresult();
				if(list.size() == 0)
				{
					break;
				}
				offset += LIMIT_TIMECARD_SIZE;
				
				copyRecords(list);
				
				if(!response.getHasMore())
				{
					break;
				}
			}
			tmpDate = new Date(tmpDate.getTime() +  TimeUnit.DAYS.toMillis(1));
		}
	}
	
	private void copyRecords(List<Recordresult> results)
		throws Exception
	{
		List<KintoneRecord> postRecs = new ArrayList<>();
		
		for(Recordresult result : results)
		{
			KintoneRecord rec = new KintoneRecord();
			
			String id = "" + result.getId();
			
			rec.setString("id", id);
			rec.setString("groupId", result.getGroupId() == null ? null : "" + result.getGroupId());
			rec.setString("planId", result.getPlanId() == null ? null : "" + result.getPlanId());
			rec.setString("recordId", result.getRecordId() == null ? null : "" + result.getRecordId());
			rec.setString("workDate", formatDate(result.getWorkDate()));
			rec.setString("userId", result.getUserId());
			rec.setString("checkType", result.getCheckType());
			rec.setString("timeResult", result.getTimeResult());
			rec.setString("locationResult", result.getLocationResult());
			rec.setString("sourceType", result.getSourceType());
			rec.setString("approveId", result.getApproveId() == null ? null : "" + result.getApproveId());
			rec.setString("procInstId", result.getProcInstId() == null ? null : "" + result.getProcInstId());
			
			rec.setString("baseCheckTime", formatDateTime(result.getBaseCheckTime()));
			rec.setString("userCheckTime", formatDateTime(result.getUserCheckTime()));
			
			Userlist user = users.get(result.getUserId());
			if(user != null)
			{
				rec.setString("userName", user.getName());
				rec.setString("userNo", user.getJobnumber());
			}
			else
			{
				rec.setString("userName", null);
				rec.setString("userNo", null);
			}
			postRecs.add(rec);
		}
		postRecordsToKintone(postRecs);
	}
	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args)
		throws Exception
	{
		//add
		//------------------------------------------------------------------------------------------
//		String date[] ={"2019-07-01","2019-07-30"};


		String appKey = "xxxxxxxxxxx";
		String appSecret = "xxxxxxxxxxx";
		String domain = "xxxxxxxxxxx.cybozu.cn";
		long appId = 116;
		long spaceId = 0;
		String apiToken = "xxxxxxxxxxx";
		//-------------------------------------------------------------------------------------------
		
		if(args.length < 2)
		{
			System.err.println("args[0]: start date(yyyy-mm-dd). args[1]: end date(yyyy-mm-dd).");
			System.exit(-1);
		}
		
		//modify
		D2TimeCardResultConnector qyd2 = new D2TimeCardResultConnector(appKey, appSecret, domain, appId, spaceId, apiToken);
		qyd2.execute(D2Connector.parseDate(args[0]), D2Connector.parseDate(args[1]));	
		
		System.out.println("success");
		
		// 開始日-終了日の設定
//		D2TimeCardResultConnector qyd2 = new D2TimeCardResultConnector("123456", "1234567890123456789012345678901234567890123", "test.cybozu.cn", 1, 0, "api_token-xxxxx");
//		qyd2.execute(D2Connector.parseDate(args[0]), D2Connector.parseDate(args[1]));		
	}
}
